<?php

class Gomoku
{
    public $nn;
    private $color;
    public $score;
    const BLACK = 1;
    const WHITE = 7;
    //private $initArray = [225, 10, 10, 10, 10, 10, 10, 225];
    private $initArray = [225, 225];

    // 1 - black, 7 - white
    public function __construct(int $color = 1, string $file = null, array $weights = null)
    {
        if ($file) {
            $nn = fann_create_from_file($file);
        } else {
            $nn = $this->randnn();
        }
        if ($weights) {
            fann_set_weight_array($nn, $weights);
        }
        $this->nn = $nn;
        $this->color = $color > 1 ? 7 : 1;
        $this->score = 0;
    }

    // 开局
    public static function newGame()
    {
        return array_pad([], 15 * 15, 0);
    }

    // 下一步
    public function next(array $input)
    {
        // 判断是不是自己的轮次
        $tb = static::turn($input);
        $mb = $this->color == 7;
        if ($tb != $mb) {
            return $input;
        }

        $tmp = fann_run($this->nn, $input);
        arsort($tmp);
        $keys = array_keys($tmp);
        foreach ($keys as $k) {
            if ($input[$k] == 0) {
                $input[$k] = $this->color;
                break;
            }
        }

        return $input;
    }

    public function setColor($color)
    {
        $this->color = $color;
        return $this;
    }

    // 判断当前轮次, 0 - 黑, 1 - 白
    public static function turn(array $input)
    {
        return (boolean) (array_sum($input) % 2);
    }

    /**
     * 胜负判断
     * 0 - 未定, 1 - 和, 2 - 黑胜, 3 - 白胜
     */
    public static function winner(array $input)
    {
        $str = join($input, ",");
        //echo "\n=========to python:\n$str\n========";
        $res = exec("python3 whoWin.py $str");
        //echo "\n=====python say:\n$res\n=========";
        return $res * 1;
    }

    public function getWeights()
    {
        return fann_get_connection_array($this->nn);
    }

    public function setWeights(array $weights)
    {
        fann_set_weight_array($this->nn, $weights);
        return $this;
    }

    public function destory()
    {
        fann_destroy($this->nn);
    }

    public function randnn()
    {
        $nn = fann_create_standard_array(2, $this->initArray);
        fann_set_activation_function_output($nn, FANN_SIGMOID);
        fann_randomize_weights($nn, -1, 1);
        return $nn;
    }
}
